//	--------------------------------------------------------------------
//	Copyright(C) 2006,2007 Zhao Yukun. All rights reserved.
//	This file is a part of the Xeres system.
//	Xeres 2007
//	Contact : xeres.engine@gmail.com
//	$(reservedInfo)
//	$(reservedDeclaration)
//	--------------------------------------------------------------------
///	@file	<IDeviceResource.h>
///	@path	~/src/graphics/
///	@date	2007/09/30
///	@desc	Device resource, including vertex buffer, index buffer or texture.

#pragma once

#include "xeres.h"

#include "graphics/IDevice.h"

#include "object/IObject.h"

namespace xeres {

	/*! 
		\class	ResourceMap
		\brief	Helper class for mapped resource.
	*/
	class ResourceMap
	{
	public:

		/// \ctor
		ResourceMap( void );

		/// \ctor
		ResourceMap( const ResourceMap& rhs );

	public:

		/// \brief	Set mapped data.
		void Map( byte * data , size_t total , size_t stride , size_t row , size_t col );

		/// \brief	Set mapped data.
		void Map( byte * data , size_t total , size_t stride , size_t row , size_t col , size_t depth , size_t slice );

		/// \brief	Set mapped data.
		void Map( byte * data , size_t total , size_t stride , size_t count );

		/// \brief	Unmap data.
		void Unmap( void );

		/// \brief	Determine if resource is mapped.
		bool IsMapped( void ) const { return m_pData != NULL; }

		/// \brief	Get data.
		byte * GetData( void ) const { return m_pData; }

		/// \brief	Texture access pixel way.
		byte * GetPixel( uint x , uint y ) const;

		/// \brief	Texture access pixel way.
		byte * GetPixel( uint x , uint y , uint z ) const;

		/// \brief	Texture access row way.
		byte * GetRow( uint y ) const;

		/// \brief	Texture access row way.
		byte * GetRow( uint y , uint z ) const;

		/// \brief	Vertex access data way.
		byte * GetVertex( uint index ) const;

		/// \brief	Index access data way.
		byte * GetIndex( uint index ) const;

		/// \brief	Get total data size.
		size_t GetTotalSize( void ) const { return m_totalData; }

		/// \brief	Get row pitch.
		size_t GetRowPitch( void ) const { return m_stride; }

		/// \brief	Get row count.
		size_t GetRowCount( void ) const { return m_row; }

		/// \brief	Get col count.
		size_t GetColCount( void ) const { return m_count; }

		/// \brief	Get depth slice.
		size_t GetDepthSlice( void ) const { return m_slice; }

		/// \brief	Get depth count.
		size_t GetDepthCount( void ) const { return m_depth; }

		/// \brief	Get vertex stride.
		size_t GetVertexStride( void ) const { return m_stride; }

		/// \brief	Get vertex count.
		size_t GetVertexCount( void ) const { return m_count; }

	private:

		//@ data
		byte *		m_pData;
		size_t		m_totalData;

		// in texture resource, stride will be row pitch size
		size_t		m_stride;
		// in texture resource, count will be col count
		size_t		m_count;
		size_t		m_row;
		size_t		m_depth;
		size_t		m_slice;
	};

	/*!
		\class	IDeviceResource
		\brief	Provide a device resource interface, to manage device allocated resources.

		\sa IDeviceCallback, IResourceManager
	*/
	class IDeviceResource : public IObject
	{
	public:

		/// \name IDeviceResource
		//@{

		/// \ctor
		IDeviceResource( void );

		/// \dtor
		virtual ~IDeviceResource( void );

		//@}
		
		DECL_IOBJECT_INTERFACE( IDeviceResource , IObject );

	public:

		/// \name IDeviceResource Interface
		//@{

		/*!
			\brief		Called when device is lost or before reset.
		*/
		virtual bool OnLostDevice( void ) = 0;

		/*!
			\brief		Called after device is reset.
		*/
		virtual bool OnResetDevice( RefWeak<IDevice> device ) = 0;

		//@}
	};

} // namespace xeres
